package com.kgc.scd.controller;

import com.kgc.scd.bean.Product;
import com.kgc.scd.contant.CommonConstant;
import com.kgc.scd.service.IndexSearchFeign;
import com.kgc.scd.service.ProductService;
import com.kgc.scd.util.*;
import lombok.extern.slf4j.Slf4j;

import org.apache.http.HttpHost;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/**
 * @program: com.kgc.scd.controller
 * @author: HarryXzy
 * @create: 2022-06-13 11:11
 * @description: 首页搜索功能 加入ES 加入敏感词过滤
 **/
@Slf4j
@RestController
public class IndexSearchController {

    @Autowired
    private RedisUtils redisUtils;
    @Autowired
    private SensitiveWordFilterUtil sensitiveWordFilterUtil;
    @Autowired
    private IndexSearchFeign indexSearchFeign;
    @Autowired
    private RedisTemplate<String,Object> redisTemplate;

    /**
    * @author: HarryXzy
    * @date: 2022/6/15 22:33
    * @return: java.util.Map<java.lang.String,java.lang.Object>
    * @description: 首页搜索
    */
    @PostMapping("/indexSearch")
    public Map<String, Object> indexSearch(@RequestParam("userId") String userId,
                                           @RequestParam(value = "searchKey")String searchKey,
                                           @RequestParam(value = "pageNo")Integer pageNo,
                                           @RequestParam(value = "pageSize")Integer pageSize,
                                           @RequestParam(value = "orderByPrice")String orderByPriceDesc) throws IOException {
        HashMap<String, Object> map = new HashMap<>();

        //if(searchKey.equals("BLMALL热卖")){
        //    Set<Object> hotKey = redisTemplate.opsForZSet().reverseRange("hotKey", 0, 1);
        //    hotKey.iterator();
        //
        //}

        // 校验搜索关键字中，是否包含敏感词，如果包含，提示错误
        if(sensitiveWordFilterUtil.isContainSensitiveWord(searchKey)){
            log.warn("------ 命中敏感词，搜索关键字：{} ------", searchKey);
            map.put("code","501");
            map.put("msg","您的搜索内容包含敏感词，请重新输入！");
            map.put("data","");
            return map;
        }
        // 没有命中敏感词
        RestHighLevelClient esClient = new RestHighLevelClient(
                RestClient.builder(new HttpHost("localhost",9200,"http"))
        );
        // 添加个人搜索记录
        indexSearchFeign.Search(userId,searchKey);
        // 判断是否命中热词
        indexSearchFeign.hotSearch(searchKey);

        // 全查
        SearchRequest searchRequest = new SearchRequest();
        searchRequest.indices(CommonConstant.BLMALL_PRODUCT_ES_INDEX);
        SearchSourceBuilder query = new SearchSourceBuilder();
        query.query(QueryBuilders.matchQuery("proName", searchKey));
        query.from(pageNo-1);
        query.size(pageSize);
        if(orderByPriceDesc.equals("1")){
            query.sort("proPrice", SortOrder.DESC);
        }
        if(orderByPriceDesc.equals("0")){
            query.sort("proPrice", SortOrder.ASC);
        }

        // 高亮展示
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        highlightBuilder.field("proName");
        highlightBuilder.preTags("<span style='color:red'>");
        highlightBuilder.postTags("</span>");
        query.highlighter(highlightBuilder);

        searchRequest.source(query);
        SearchResponse response = esClient.search(searchRequest, RequestOptions.DEFAULT);

        // 高亮显示
        ArrayList<Map<String,Object>> products = new ArrayList<>();
        for(SearchHit hit : response.getHits().getHits()){
            Map<String, HighlightField> highlightFields = hit.getHighlightFields();
            HighlightField proName = highlightFields.get("proName");
            Map<String, Object> sourceAsMap = hit.getSourceAsMap();
            if(proName != null){
                Text[] fragments = proName.fragments();
                String n_name="";
                for(Text text : fragments){
                    n_name += text;
                }
                sourceAsMap.put("proName",n_name);
            }
            products.add(sourceAsMap);
        }
        PageSupport<Map<String, Object>> pageSupport = new PageSupport<>();
        pageSupport.setPageData(products);
        pageSupport.setPageNo(pageNo);
        pageSupport.setPageSize(pageSize);
        String s = response.getHits().getTotalHits().toString();
        String s1 = s.replaceAll(" hits", "");
        Integer integer = Integer.valueOf(s1);
        pageSupport.setTotalCount(integer);
        map.put("code",CommonConstant.UNIFY_RETURN_SUCCESS_CODE);
        map.put("msg",CommonConstant.UNIFY_RETURN_SUCCESS_MSG);
        map.put("data",pageSupport);
        return map;
    }


}
